package com.qt.service.oj.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qt.enums.ApiExceptionEnum;
import com.qt.exception.ApiException;
import com.qt.mapper.ProblemMapper;
import com.qt.pojo.dto.ProblemQueryDTO;
import com.qt.pojo.entity.problem.Problem;
import com.qt.pojo.vo.JudgeProblemResultVO;
import com.qt.pojo.vo.ProblemInfoVO;
import com.qt.pojo.vo.ProblemVO;
import com.qt.result.R;
import com.qt.service.LanguageService;
import com.qt.service.oj.JudgeService;
import com.qt.service.oj.ProblemService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author pgw
 * @version 1.0
 * @description
 * @date Create by 2023/9/23 20:38
 */
@Slf4j
@Service
public class ProblemServiceImpl  extends ServiceImpl<ProblemMapper, Problem>  implements ProblemService {

    @Autowired
    private  ProblemMapper problemMapper;

    @Autowired
    private JudgeService judgeService;

    @Autowired
    private LanguageService languageService;

    @Override
    public R getProblemList(ProblemQueryDTO problemQueryDto) {
        Long pageSize = Optional.ofNullable(problemQueryDto.getPageSize()).orElse(30L);
        Long currentPage = Optional.ofNullable(problemQueryDto.getCurrentPage()).orElse(1L);
        String oj = problemQueryDto.getOj();
        List<Long> tagIds = problemQueryDto.getTagIds();
        String keyword = problemQueryDto.getKeyword();
        Integer difficulty = problemQueryDto.getDifficulty();
        if (!StringUtils.isEmpty(keyword)) {
            keyword = keyword.trim();
        }
        Integer tagListSize = null;
        if (tagIds != null) {
            tagIds = tagIds.stream().distinct().collect(Collectors.toList());
            tagListSize = tagIds.size();
        }
        Page<ProblemVO> page = new Page<>(currentPage , pageSize);
        List<ProblemVO> problemList = problemMapper.getProblemList((currentPage - 1) * pageSize, pageSize, oj, difficulty, keyword , tagIds , tagListSize);
        if(problemList.size() > 0){
            List<Long> problemIds = problemList.stream().map(ProblemVO::getId).collect(Collectors.toList());
            List<JudgeProblemResultVO> judgeProblemStatusList = judgeService.getJudgeProblemStatus(problemIds);
            for(ProblemVO problemVo : problemList){
                for(JudgeProblemResultVO judgeProblemResultVo : judgeProblemStatusList){
                    if(problemVo.getId().equals(judgeProblemResultVo.getId())){
                         problemVo.setProblemResultVo(judgeProblemResultVo);
                         break;
                    }
                }
            }

        }
        page.setRecords(problemList);
        page.setTotal(problemList.size());
        return  R.success(page);
    }


    @Override
    public R getProblemDetail(Long id) {
        Problem problem = problemMapper.selectById(id);
        if(problem == null){
            throw  new ApiException(ApiExceptionEnum.PROBLEM_NOT_FOUND);
        }
        List<JudgeProblemResultVO> judgeProblemStatusList = judgeService.getJudgeProblemStatus(Collections.singletonList(id));
        List<String> languageNames = languageService.getLanguageNames();
        ProblemInfoVO problemInfoVO = new ProblemInfoVO();
        problemInfoVO.setProblem(problem);
        problemInfoVO.setJudgeProblemResultVO(judgeProblemStatusList.get(0));
        problemInfoVO.setLanguages(languageNames);
        return R.success(problemInfoVO);
    }
}
